#include "common.h"
#include "IO.h"


bool isValid(int index)
{
	int colorIndex = g_adjacencyList[index].colorIndex;
	
	NodeRef* neighbor = g_adjacencyList[index].nodeRef;
	while (neighbor)
	{
		if (neighbor->node->id > g_adjacencyList[index].id)
		{
			neighbor = neighbor->next;
			continue;
		}
		int neighborColor = neighbor->node->colorIndex;
		if ( neighborColor != COLOR_COUNT && neighborColor == colorIndex)
		{
			return false;
		}
		neighbor = neighbor->next;
	}

	return true;
}

void remapColor()
{
	int index = 0;
	while (g_adjacencyList[0].colorIndex < COLOR_COUNT)
	{
		if (g_adjacencyList[index].colorIndex == COLOR_COUNT)
		{
			g_adjacencyList[--index].colorIndex++;
			continue;
		}
		if (isValid(index))
		{
			if (index == ACTIVATED_NODE_COUNT - 1)
			{
				return;
			}
			else
			{
				g_adjacencyList[++index].colorIndex = 0;
			}
		}
		else
		{
			g_adjacencyList[index].colorIndex++;
		}
	}

}

void outputFile(property_tree::wptree& configXML)
{
	if (g_adjacencyList[0].colorIndex == COLOR_COUNT)
	{
		return;
	}

	property_tree::wptree earthXML;
	string filename = wstringToString(configXML.get<wstring>(L"config.earthFile"));
	readXML(filename, earthXML);


	int* colorIndex = new int[ACTIVATED_NODE_COUNT + INACTIVATED_NODE_COUNT];
	for (int i = 0; i < ACTIVATED_NODE_COUNT + INACTIVATED_NODE_COUNT; i++)
	{
		int indexInGeode = g_adjacencyList[i].indexInGeodeList;
		colorIndex[indexInGeode] = g_adjacencyList[i].colorIndex;
	}

	int i = 0;
	BOOST_FOREACH(property_tree::wptree::value_type& v, earthXML.get_child(L"map"))
	{
		if (wcscmp(v.first.data(), L"model") != 0) { continue; }

		wstring name = v.second.get<wstring>(L"features.<xmlattr>.name");
		wstringstream strOut;
		strOut << name << L"{ fill: #" << g_colors[ colorIndex[i++] ] << L";}";
		v.second.put(L"styles.style", strOut.str());
		v.second.put(L"styles.style.<xmlattr>.type", L"text/css");
	}

	delete [] colorIndex;
	writeXML(filename, earthXML);
	
}

void display()
{
	if (g_adjacencyList[0].colorIndex == COLOR_COUNT)
	{
		cout << "Couldn't find a solution." << endl;
		return;
	}

	for (int i = 0; i < ACTIVATED_NODE_COUNT + INACTIVATED_NODE_COUNT; ++i)
	{
		cout << g_adjacencyList[i].name << ": " << g_adjacencyList[i].colorIndex << endl;
	}
}

int main(int argc, char** argv)
{
	if (argc == 1)
	{
		return 0;
	}

#if 0
	initAdjacencyListManully();
	initColorsManully();
#else
	property_tree::wptree configXML;
	if (!readXML(argv[1], configXML))
	{
		return -1;
	}

	initAdjacencyListAutomatically(configXML);
	initColorsAutomatically(configXML);
#endif

	remapColor();
	outputFile(configXML);
	display();

	destroyAdjacencyList();
	destroyColors();

	system("pause");
	return 0;
}
